import { fabric } from "@/js/fabric";
import shUtils from "./util";
import interactive from "@/js/fabric.interactive.js";
import rluer from "@/js/rluer.js";
import history from "@/js/sc_history.js";
function BaseCanvas() {
  fabric.Canvas.apply(this, arguments);
};
(function () {
  // 创建一个没有实例方法的类
  var Super = function () { };
  Super.prototype = fabric.Canvas.prototype;
  //将实例作为子类的原型
  BaseCanvas.prototype = new Super();
  BaseCanvas.prototype.init = function () {
    this._scaleFun();
    this.setDragstate(true);
    this.setScalestate(true);
    this._addJiaohu();
    this._addhistory();
    dispatchEvent.call(this, eventlist, findhotpotsFloows);
    this.on("mouse:over", function (e) {
      let target = e.target;
      if (target && target instanceof fabric.Group) {
        target._objects.forEach(item => {
          item.set("fillOringin", item.get("stroke"))
          item.set("stroke", "green");
        });
      }
      if (target) {
        target.set("fillOringin", target.get("stroke"))
        target.set("stroke", "green");
      }
      target && target.canvas.renderAll()
    })
    this.on("mouse:out", function (e) {
      let target = e.target;
      if (target && target instanceof fabric.Group) {
        target._objects.forEach(item => {
          item.set("stroke", item.get("fillOringin"))
          item.canvas.renderAll()
        });
      }
      if (target) {
        target.set("stroke", target.get("fillOringin"))
      }
      target && target.canvas.renderAll()
    })
    this.on("object:added", function (e) {
      this.did = !this.did ? 1 : this.did++;
      !e.target.get("did") && e.target.set("did", this.did++);
    });
  };
  BaseCanvas.prototype._scaleFun = function () {
    this.on("mouse:wheel", function (e) {
      if (this.scaleState) {
        event.preventDefault(); //阻止事件冒泡
        var zoom = (event.deltaY < 0 ? 0.2 : -0.3) + this.getZoom();
        zoom = Math.max(0.1, zoom); //最小为原来的1/10
        zoom = Math.min(10, zoom); //最大是原来的3倍
        var zoomPoint = e.pointer;
        this.zoomToPoint(zoomPoint, zoom);
        this.fire("ruler", {});
      }
    });
  }
  BaseCanvas.prototype._drawPositon = function (e) {
    let ctx = this.getContext();
    // ctx.clearRect(0,0,1200,600);
    this.renderAll();
    ctx.beginPath();
    ctx.moveTo(e.pointer.x, 0);
    ctx.lineTo(e.pointer.x, 600);
    ctx.moveTo(0, e.pointer.y);
    ctx.lineTo(1200, e.pointer.y);
    ctx.fillText(e.absolutePointer.x.toFixed(2) + "," + e.absolutePointer.y.toFixed(2), e.pointer.x + 10, e.pointer.y - 10);
    ctx.stroke();
  }
  BaseCanvas.prototype.setDragstate = function (type) {
    this.dragState = type
  }
  BaseCanvas.prototype.setScalestate = function (type) {
    this.scaleState = type
  }
  BaseCanvas.prototype.addRluer = function () {
    if (!this.ruler) {
      this.ruler = new rluer({ canvas: this });
      this.ruler.add("top");
      this.ruler.add("left");
      this.ruler.add("right");
    }
    this.off("ruler")
    this.on("ruler", function (e) {
      this.ruler.draw();
    })
  }
  BaseCanvas.prototype.getRluer = function () {
    return this.ruler
  }
  BaseCanvas.prototype._addJiaohu = function () {
    let canvas = this;
    if (!this.maskCanvas) {
      let maskCanvasEl = shUtils.createEl(canvas);
      this.wrapperEl.parentNode.append(maskCanvasEl);
      let canvasMask = this.maskCanvas = new fabric.Canvas(maskCanvasEl);
      canvasMask.root = canvas
      this.maskCanvasEl = canvasMask.wrapperEl;
      this._scaleFun.apply(this.maskCanvas, arguments);
      this.setDragstate.apply(this.maskCanvas, arguments);
      this.setScalestate.apply(this.maskCanvas, arguments);
      canvasMask.off("mouse:wheel").on("mouse:wheel", function (e) {
        canvas.fire("mouse:wheel", e);
        canvas.jiaozhu();
      });
      canvasMask.off("ruler").on("ruler", function (e) {
        canvas.fire("ruler", {});
      });
      canvas.on("mouse:wheel", function () {
        canvas.jiaozhu();

      })
      canvas.on("draging", function () {
        canvas.jiaozhu();
      })
      canvasMask.off("dragstart").on("dragstart", function (e) {

        canvas.fire("mouse:down", e);
      });
      canvasMask.off("draging").on("draging", function (e) {
        canvas.fire("mouse:move", e);
        canvas.jiaozhu();
      });
      canvasMask.off("dragend").on("dragend", function (e) {
        canvas.fire("mouse:up", e);
        canvas.jiaozhu();
      });
      canvasMask.off("drawend").on("drawend", function (e) {
        canvas.chooseDrawtype("")
      });
      canvasMask.off("add").on("add", function (e) {
        canvasMask.remove(e.target);
        canvas.add(e.target);
        e.target.evented = true
        e.target.setCoords();
        canvas.renderAll();
      })
    }
    this.addInteractive();
  }
  BaseCanvas.prototype.tongbu = function () {
    let Canvas1El = this.wrapperEl;
    let Canvas2El = this.maskCanvasEl;
    Canvas1El.style.position = "absolute"
    Canvas2El.style.position = Canvas1El.style.position;
    Canvas2El.style.left = 0;
    Canvas2El.style.top = 0;
    Canvas2El.style.zIndex = 77;
    Canvas2El.style.pointerEvents = "auto";
    this.jiaozhu()
  }
  BaseCanvas.prototype._addhistory = function () {
    if (!this.history) {
      this._history = new history(this);
    }
  }
  BaseCanvas.prototype.getHistory = function () {
    return this._history
  }
  BaseCanvas.prototype.jiaozhu = function () {
    let Canvas1 = this;
    let Canvas2 = this.maskCanvas;
    Canvas2.setViewportTransform(Canvas1.viewportTransform)
    // Canvas2.viewportTransform = Canvas1.viewportTransform;
    Canvas2.renderAll();
  }
  BaseCanvas.prototype.addInteractive = function () {
    if (!this.sh_maskinteractive) {
      this.sh_maskinteractive = new interactive(this.maskCanvas, {
        options: {
          drawing: false,
          drawtype: "",
          isDrawingMode: true
        }
      });
    }
    if (!this.sh_interactive) {
      this.sh_interactive = new interactive(this, {
        options: {
          drawing: false,
          drawtype: "",
          isDrawingMode: false
        }
      });
    }
    this.tongbu();
  }
  BaseCanvas.prototype.getInteractor = function () {
    return this.sh_interactive
  }
  BaseCanvas.prototype.getMaskInteractor = function () {
    return this.sh_maskinteractive
  }
  BaseCanvas.prototype.drawStart = function () {
    this.maskCanvasEl.style.pointerEvents = "auto";
    this.jiaozhu();
  }
  BaseCanvas.prototype.drawEnd = function () {
    this.maskCanvasEl.style.pointerEvents = "none";
    this.jiaozhu();
  }
  /*
   * 关闭编辑模式
   */
  BaseCanvas.prototype.draweditable = function (type) {
    this.sh_maskinteractive.setOptions("isDrawingMode", type);
    this.maskCanvasEl.style.pointerEvents = type ? "auto" : "none"
  }
  BaseCanvas.prototype.chooseDrawtype = function (type) {
    this.discardActiveObject();
    this.renderAll();
    this.sh_maskinteractive.setOptions("drawtype", type);
    this.maskCanvasEl.style.pointerEvents = !type ? "none" : "auto";
    this.jiaozhu();
  }
  BaseCanvas.prototype.getdrawtype = function () {
    return this.sh_maskinteractive.getOptions("drawtype")
  }
  let eventlist = ["object:moving", "object:scaling", "object:rotating"];
  function dispatchEvent(eventlist, fn) {
    let _that = this
    eventlist.forEach(item => {
      _that.on(item, function (e) {
        fn(e)
      })
    })
  }
  function findhotpotsFloows(e) {
    var target = e.target;
    //组图元和活跃图元存在差异，需单独处理
    if (target.type == "activeSelection") {
      target._objects.forEach(element => {
        checkhotpot(element);
      });
    } else {
      checkhotpot(target);
    }
  }
  function checkhotpot(target) {
    for (let key in target.hotpotslist) {
      target.hotpotslist[key].forEach(item => {
        let point = _gethotpot.call(target, key)
        if (item.source === target) {
          if (item instanceof fabric.Polyline) {
            item.points.shift();
            item.points.unshift(point);
          } else {
            item.set({ x1: point.x, y1: point.y })
          }
        }
        if (item.target === target) {
          if (item instanceof fabric.Polyline) {
            item.points.pop();
            item.points.push(point)
          } else {
            item.set({ x2: point.x, y2: point.y })
          }
          // item.set({ x2: point.x, y2: point.y })
        }
      })
    }
  }
  function _gethotpot(hotid) {
    let item;
    let list = this._objects.filter(item => {
      return item.hotid === hotid
    });
    item = list[0];
    return getpoint(item, item.getCenterPoint())
  }
  function getpoint(item, point) {
    let callback = getpoint;
    if (item.group) {
      point = new fabric.Point(
        point.x * item.scaleX +
        item.group.getCenterPoint().x,
        point.y * item.scaleY +
        item.group.getCenterPoint().y
      );
      point = fabric.util.rotatePoint(
        point,
        item.group.getCenterPoint(),
        fabric.util.degreesToRadians(item.group.angle)
      )
      return callback(item.group, point)
    } else {
      return point
    }

  }
  function mouseover() {
    this.on("mouse:over", function (e) {
      console.log(e)
    })
  }
})();
// let BaseCanvas = fabric.util.createClass(fabric.Canvas,/** @lends fabric.Group.prototype */{

// })

export default BaseCanvas;